import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By


class EasyTest:
    def __init__(self, driver, url):
        self.driver = driver
        self.url = url
        self.driver.get(self.url)
        time.sleep(3)
        # self.log = Log().logger

    def add_token(self, token_key, token_value):
        self.driver.get(self.url)
        js = '''window.localStorage.setItem('{}','{}')'''.format(token_key, token_value)
        self.driver.execute_script(js)

    def open_url(self, url):
        self.driver.get(url)
        time.sleep(5)

    def locator(self, *loc, driver=None):
        '''元素定位 支持各种定位方式'''
        loc = loc[0] if len(loc) == 1 else loc
        try:
            if driver:
                return driver.find_element(*loc)
            return self.driver.find_element(*loc)
        except:
            return None

    def locators(self, *loc, driver=None):
        loc = loc[0] if len(loc) == 1 else loc
        if driver:
            return driver.find_elements(*loc)
        return self.driver.find_elements(*loc)

    def get_title(self):
        return self.driver.title

    def quit(self):
        self.driver.quit()

    def get_input_value(self):
        inputs = self.locators(By.XPATH, '//input[@type="text"]')
        return [input_.get_attribute('value') for index, input_ in enumerate(inputs)]

    def get_input(self, text, index=None):
        # TODO textarea 文本框
        nodes = self.locators(By.XPATH,
                              "//*[contains(@placeholder,'{0}')] | //*/text()[contains(.,'{0}')]/..".format(text))

        def get_input_child(parent_node):
            return self.locators(By.TAG_NAME, 'input', driver=parent_node)

        for node in nodes:
            if node.tag_name == 'input':
                return node

            while len(get_input_child(node)) == 0:
                node = self.locator(By.XPATH, '..', driver=node)
            inputs = get_input_child(node)
            if len(inputs) == 1:
                return inputs[0]
            elif index:
                return inputs[index-1]
        return None

    def get_button(self, text, index=1):
        """
        input type=submit
        button标签直接包含  button子节点
        a链接  a链接下img
        class  包含btn
        /ancestor::a[1]  向上查找第一个父级a标签
        """
        button_tag = (By.XPATH, "(//button[contains(.,'{0}')])[{1}]".format(text, index))
        input_tag = (By.XPATH, "(//input[@type='submit' and contains(@value,'{0}')])[{1}]".format(text, index))
        a_tag = (By.XPATH, "(//a[contains(.,'{0}')])[{1}]".format(text, index))
        other_tag = (By.XPATH, "(//*[contains(@class,'btn') and contains(.,'{0}')])[{1}]".format(text, index))

        return self.locator(button_tag) or self.locator(input_tag) or self.locator(a_tag) or self.locator(other_tag)

    def get_radio(self, text, index=None):
        # index 从1开始  当父节点下有多个节点近似于目标节点,需指定第几个节点

        def _get_radio(n):
            input_ = ".//input[@type='radio']"
            el_ = ".//*[contains(@class,'el-radio')]"
            layui = ".//*[contains(@class,'layui-anim') and contains(@class,'layui-icon')]"

            res = self.locators(By.XPATH, "{} | {} | {}".format(input_, el_, layui), driver=n)
            return res

        loc_nodes = (By.XPATH, "//*/text()[contains(.,'{}')]/..".format(text))
        nodes = self.locators(loc_nodes)

        for node in nodes:
            input_ = node.tag_name == 'input' and node.get_attribute('type') == 'radio'
            el_ = 'el-radio' in node.get_attribute('class')
            layui = 'layui-anim' in node.get_attribute('class') and 'layui-icon' in node.get_attribute('class')

            if el_ or layui or input_:
                return node
            while len(_get_radio(node)) == 0:
                node = self.locator(By.XPATH, '..', driver=node)
            radios = _get_radio(node)
            if len(radios) == 1:
                return radios[0]
            elif index:
                return radios[index - 1]
        return None

    def get_checkbox(self, text, index=None):
        # index 从1开始  当父节点下有多个节点近似于目标节点,需指定第几个节点
        def _get_checkbox(n):
            input_ = ".//input[@type='checkbox']"
            el_ = ".//*[contains(@class,'el-checkbox')]"
            layui_ = ".//*[contains(@class,'layui-icon') and contains(@class,'layui-icon-ok')]"
            return self.locators(By.XPATH, "{} | {} | {}".format(input_, el_, layui_), driver=n)

        nodes = self.locators(By.XPATH, "//*/text()[contains(.,'{0}')]/..".format(text))

        for node in nodes:
            input_ = node.tag_name == 'input' and node.get_attribute('type') == 'checkbox'
            el_ = 'el-checkbox' in node.get_attribute('class')
            layui = 'layui-icon' in node.get_attribute('class') and 'layui-icon-ok' in node.get_attribute('class')

            if el_ or layui or input_:
                return node
            while len(_get_checkbox(node)) == 0:
                node = self.locator(By.XPATH, '..', driver=node)
            boxs = _get_checkbox(node)
            if len(boxs) == 1:
                return boxs[0]
            elif index:
                return boxs[index - 1]
        return None

    def is_select_(self, type, text, index=None):
        # index 从1开始  当父节点下有多个节点近似于目标节点,需指定第几个节点
        if type == 'radio':
            node = self.get_radio(text, index)
        elif type == 'checkbox':
            node = self.get_checkbox(text, index)
        else:
            raise TypeError('type类型错误----------')

        def _get_input(n):
            loc = (By.XPATH, ".//input[@type='{}']".format(type))
            return self.locators(loc, driver=n)

        if node == None:
            raise TypeError('没找到 结果为None,------------')
        if node.tag_name == 'input' and node.get_attribute('type') == type:
            return node.is_selected()
        else:
            parent_node = node
            while len(_get_input(parent_node)) == 0:
                parent_node = self.locator(By.XPATH, '..', driver=parent_node)
            inputs = _get_input(parent_node)
            if len(inputs) == 1:
                return inputs[0].is_selected()
            elif index:
                return inputs[index-1].is_selected()
            raise TypeError('此类型暂不支持,请手动定位------------')

    def get_select_options(self, text):
        # role = 'option'
        node = self.locator(By.XPATH, "//select//*/text()[contains(.,'{}')]/..".format(text))
        return node

    def get_table_data(self, index=None, loc_rows=None, loc_key=None):
        """
        index  第几个table  从1开始
        loc_rows  定位table每一行
        loc_key   定位每一行下的列
        """
        if not loc_rows:
            regular = '(//table)[{}]//tr'.format(index) if index else '//table//tr'
            loc_rows = (By.XPATH, regular)

        rows = self.locators(loc_rows)  # 行
        datas = []
        for row in rows:
            loc = loc_key if loc_key else (By.XPATH, 'th | td')
            keys = self.locators(loc, driver=row)
            # textContent会获取style = “display: none” 中的文本 text不会
            row_data = [key.get_attribute('textContent') for key in keys]
            datas.append(row_data) if row_data else False
        return datas

    def js_click(self, node):

        self.driver.execute_script('arguments[0].click()', node)

    def test(self):
        self.open_url('https://jui.org')
        self.get_button('组合应用').click()
        time.sleep(2)
        self.get_button('局部刷新分页1').click()
        time.sleep(2)
        self.get_button('尿检').click()
        time.sleep(2)
        loc = (By.XPATH, "//*/text()[contains(.,'阴性')]/..")
        res = self.locator(loc)
        print(res.text, 1111111111111111111111)

#
# b = EasyTest(webdriver.Chrome(), 'https://jui.org')
# b.test()
